package ltd.hxya.novel.springsecurity.aop;

import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import ltd.hxya.novel.common.constant.rabbit.RabbitConstant;
import ltd.hxya.novel.common.vo.OperLog;
import ltd.hxya.novel.common.anno.OperLogAnno;
import ltd.hxya.novel.springsecurity.utils.OperationUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

@Slf4j
@Aspect
@Component
public class WebOperLogAop {
    @Autowired
    private RabbitTemplate rabbitTemplate;


    @Pointcut("@annotation(operLogAnno)")
    public void operlog(OperLogAnno operLogAnno){}

    @AfterReturning(value = "operlog(operLogAnno)",returning = "result")
    public void saveReturnLog(JoinPoint joinPoint, OperLogAnno operLogAnno, Object result) throws Throwable {
        OperLog operLog = saveLog(joinPoint, operLogAnno);
        operLog.setJsonResult(JSON.toJSONString(result));
        log.info(JSON.toJSONString(operLog));
        operLog.setStatus(1);
        //调用远程服务，将操作日志添加到数据库中
        rabbitTemplate.convertAndSend(RabbitConstant.OPER_LOG_ADD_EXCHANGE,RabbitConstant.OPER_LOG_ADD_ROUTING_KEY,operLog);
    }

    @AfterThrowing(value = "operlog(operLogAnno)")
    public void saveThrowLog(JoinPoint joinPoint, OperLogAnno operLogAnno) throws Throwable {
        OperLog operLog = saveLog(joinPoint, operLogAnno);
        log.info(JSON.toJSONString(operLog));
        operLog.setStatus(0);
        //调用远程服务，将操作日志添加到数据库中
        rabbitTemplate.convertAndSend(RabbitConstant.OPER_LOG_ADD_EXCHANGE,RabbitConstant.OPER_LOG_ADD_ROUTING_KEY,operLog);
    }

    public static OperLog saveLog(JoinPoint joinPoint,OperLogAnno operLogAnno){
        OperLog operLog = OperationUtils.getOperation(operLogAnno);
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        operLog.setMethod(signature.getMethod().getName());
        Object[] args = joinPoint.getArgs();
        String argString = null;
        for (Object arg : args) {
           if (StringUtils.isEmpty(argString)){
               argString = new String();
           }else {
               argString = argString +" ";
           }
           argString = argString + JSON.toJSONString(arg);
        }
        operLog.setOperParam(argString);
        return operLog;
    }

}
